home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 2
/
CU Amiga Magazine's Super CD-ROM 02 (1996)(EMAP Images)(GB)[!][issue 1996-04].iso
/
magazine
/
amiga_e
/
epp
/
pmodules
/
mdarray.e
< prev
next >
Wrap
Text File
|
1980-01-05
|
5KB
|
156 lines
/*========================================================================*/
/* */
/* Multi-Dimensional arrays in E. */
/* */
/*========================================================================*/
PMODULE 'PMODULES:listItem'
RAISE "MEM" IF New () = NIL,
"MEM" IF List () = NIL
CONST SIZEOF_CHAR = 1,
SIZEOF_INT = 2,
SIZEOF_LONG = 4
OBJECT md_arrayType
uBound : LONG
elementSize : LONG
numberOfDimensions : LONG
sizeOfDimension : LONG
elements : LONG
ENDOBJECT
/*-- Set this to the value of the exception to be --*/
/*-- raised if any of the array bounds checks fails. --*/
/*-- Default of -1 means raise no exception. --*/
DEF md_constraintError = -1
PROC md_handleConstraintError ()
IF md_constraintError <> -1 THEN Raise (md_constraintError)
ENDPROC
PROC md_dim (array : PTR TO md_arrayType,
indexList : PTR TO LONG,
elementSize) /*-- Use one of the provided constants. --*/
DEF numberOfElements = 1,
sizeOfDimension = NIL : PTR TO LONG,
i, j
/*-- Compute number of elements and create array. --*/
array.elementSize := elementSize
array.numberOfDimensions := ListLen (indexList)
FOR i := 0 TO (array.numberOfDimensions - 1) DO numberOfElements := Mul (numberOfElements, indexList [i])
array.elements := New (Mul (numberOfElements, elementSize))
/*-- Store upper bounds of each dimension. --*/
array.uBound := List (array.numberOfDimensions)
ListCopy (array.uBound, indexList, ALL)
MapList ({i}, array.uBound, array.uBound, `i - 1)
/*-- Compute and store size of each dimension for later index computations. --*/
/*-- Init list. --*/
array.sizeOfDimension := List (array.numberOfDimensions)
SetList (array.sizeOfDimension, array.numberOfDimensions)
MapList ({i}, array.sizeOfDimension, array.sizeOfDimension, `1)
/*-- Compute size of each dimension. --*/
sizeOfDimension := array.sizeOfDimension
FOR i := 0 TO (array.numberOfDimensions - 1)
FOR j := (i + 1) TO (array.numberOfDimensions - 1)
sizeOfDimension [i] := Mul (sizeOfDimension [i], indexList [j])
ENDFOR
ENDFOR
ENDPROC
/* md_dim */
PROC md_withinBounds (array : PTR TO md_arrayType,
indexList : PTR TO LONG)
DEF i
FOR i := 0 TO (array.numberOfDimensions - 1) DO IF (indexList [i] < 0) OR
(indexList [i] > listItem (array.uBound, i)) THEN RETURN FALSE
ENDPROC TRUE
/* md_withinBounds */
PROC md_offset (array : PTR TO md_arrayType,
indexList : PTR TO LONG)
DEF offset = 0, i
FOR i := 0 TO (array.numberOfDimensions - 1)
offset := offset + Mul (indexList [i],
listItem (array.sizeOfDimension, i))
ENDFOR
ENDPROC Mul (offset, array.elementSize)
/* md_offset */
PROC md_set (array : PTR TO md_arrayType,
indexList : PTR TO LONG,
value)
DEF charPtr : PTR TO CHAR,
intPtr : PTR TO INT,
longPtr : PTR TO LONG,
elementSize
IF md_withinBounds (array, indexList)
elementSize := array.elementSize
SELECT elementSize
CASE SIZEOF_CHAR
charPtr := array.elements + md_offset (array, indexList)
charPtr [] := value
CASE SIZEOF_INT
intPtr := array.elements + md_offset (array, indexList)
intPtr [] := value
CASE SIZEOF_LONG
longPtr := array.elements + md_offset (array, indexList)
longPtr [] := value
ENDSELECT
ELSE
md_handleConstraintError ()
ENDIF
ENDPROC
/* md_set */
PROC md_get (array : PTR TO md_arrayType,
indexList : PTR TO LONG)
DEF charPtr : PTR TO CHAR,
intPtr : PTR TO INT,
longPtr : PTR TO LONG,
elementSize
IF md_withinBounds (array, indexList)
elementSize := array.elementSize
SELECT elementSize
CASE SIZEOF_CHAR
charPtr := array.elements + md_offset (array, indexList)
RETURN charPtr []
CASE SIZEOF_INT
intPtr := array.elements + md_offset (array, indexList)
RETURN intPtr []
CASE SIZEOF_LONG
longPtr := array.elements + md_offset (array, indexList)
RETURN longPtr []
ENDSELECT
ELSE
md_handleConstraintError ()
ENDIF
ENDPROC
/* md_get */
PROC md_dispose (array : PTR TO md_arrayType)
Dispose (array.uBound)
Dispose (array.elements)
ENDPROC
/* md_dispose */